/* eslint-disable no-case-declarations */
/* eslint-disable no-debugger */
// axios配置  可自行根据项目进行更改，只需更改该文件即可，其他文件可以不动
import { VAxios } from "./Axios";
import { AxiosTransform } from "./axiosTransform";
import axios, { AxiosResponse } from "axios";
import { checkStatus } from "./checkStatus";
import { joinTimestamp, formatRequestDate } from "./helper";
import { RequestEnum, ResultEnum, ContentTypeEnum } from "@/enums/httpEnum";
import { PageEnum } from "@/enums/PageEnum";
import { notification, Modal, message } from "antd";
// import { useGlobSetting } from "@/hooks/setting";
import { isString } from "@/utils/is";
import { deepMerge, isUrl } from "@/utils";
import { setObjToUrlParams } from "@/utils/urlUtils";
import { RequestOptions, Result, CreateAxiosOptions } from "./types";

// import { useUser } from "@/store/modules/user";

// const globSetting = useGlobSetting();
const urlPrefix = import.meta.env.VITE_GLOB_API_URL_PREFIX || "";
const clientId = import.meta.env.VITE_GLOB_CLIENT_ID || "";
const tenantId = import.meta.env.VITE_GLOB_CLIENT_ID || "";
// import router from "@/router";
import { storage } from "@/utils/Storage";
import useToken from "@/hooks/useToken";
import { AxiosCanceler } from "./axiosCancel";
const axiosCanceler = new AxiosCanceler();

/**
 * @description: 数据处理，方便区分多种处理方式
 */
const transform: AxiosTransform = {
	/**
	 * @description: 处理请求数据
	 */
	transformRequestData: (res: AxiosResponse<Result>, options: RequestOptions) => {
		const {
			isShowMessage = true,
			isShowErrorMessage,
			isShowSuccessMessage,
			successMessageText,
			errorMessageText,
			isTransformResponse = false,
			isReturnNativeResponse
		} = options;
		// 是否返回原生响应头 比如：需要获取响应头时使用该属性
		if (isReturnNativeResponse) {
			return res;
		}
		const { data } = res;
		// 不进行任何处理，直接返回
		// 用于页面代码可能需要直接获取code，data，message这些信息时开启
		if (isTransformResponse) {
			if (data?.success) {
				return Promise.resolve(res?.data?.data);
			} else if (data?.isSuccess) {
				return Promise.resolve(res?.data?.data);
			} else {
				// let errorMsg = data.msg;
				// switch (code) {
				// 	// 请求失败
				// 	case ResultEnum.ERROR:
				// 		message.error(errorMsg);
				// 		break;
				// 	//没有权限
				// 	case ResultEnum.NOT_PRMISSION:
				// 		message.error(errorMsg);
				// 		break;
				// 	// 登录超时
				// 	case ResultEnum.TIMEOUT:
				// 		// 到登录页
				// 		errorMsg = "登录超时，请重新登录!";
				// 		Modal.warning({
				// 			title: "提示",
				// 			content: errorMsg,
				// 			okText: "重新登录",
				// 			onOk: () => {
				// 				window.location.href = PageEnum.LOGIN_PATH;
				// 			}
				// 		});
				// 		break;
				// 	case ResultEnum.NOT_AUTH:
				// 		Modal.warning({
				// 			title: "登录过期提示",
				// 			content: errorMsg,
				// 			okText: "重新登录",
				// 			onOk: () => {
				// 				window.location.href = PageEnum.LOGIN_PATH;
				// 			}
				// 		});
				// }
				handleSwitch(data);
			}
			// return res?.data?.data;
		}
		if (!data) {
			throw new Error("请求出错，请稍候重试");
		}
		if (data?.success) {
			return Promise.resolve(res.data);
		} else if (data?.isSuccess) {
			return Promise.resolve(res.data);
		}
		// @ts-ignore
		let errorMsg = data.msg;
		handleSwitch(data);
		throw new Error(errorMsg);

		//  这里 code，result，message为 后台统一的字段，需要修改为项目自己的接口返回格式
		// const { code, msg } = data;
		// const respData = data?.data;

		// // 请求成功
		// const hasSuccess = data && Reflect.has(data, "code") && code === ResultEnum.SUCCESS;
		// // 是否显示提示信息
		// if (isShowMessage) {
		// 	if (hasSuccess && (successMessageText || isShowSuccessMessage)) {
		// 		// 是否显示自定义信息提示
		// 		const msg = (successMessageText || msg || "操作成功！") as string;
		// 		message.success(msg);
		// 	} else if (!hasSuccess && (errorMessageText || isShowErrorMessage)) {
		// 		// 是否显示自定义信息提示
		// 		const msg = (message || errorMessageText || "操作失败！") as unknown as string;
		// 		message.error(msg);
		// 	} else if (!hasSuccess && options.errorMessageMode === "modal") {
		// 		Modal.warning({
		// 			title: "提示",
		// 			content: message as unknown as string,
		// 			okText: "重新登录"
		// 		});
		// 	}
		// }
		// // 接口请求成功，直接返回结果
		// if (code === ResultEnum.SUCCESS) {
		// 	return respData;
		// }
		// // 接口请求错误，统一提示错误信息 这里逻辑可以根据项目进行修改
	},

	// 请求之前处理config
	beforeRequestHook: (config, options) => {
		const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true, urlPrefix } = options;

		const isUrlStr = isUrl(config.url as string);

		if (!isUrlStr && joinPrefix) {
			config.url = `${urlPrefix}/${config.url}`;
		}

		if (!isUrlStr && apiUrl && isString(apiUrl)) {
			config.url = `${apiUrl}${config.url}`;
		}
		const params = config.params || {};
		const data = config.data || false;
		if (config.method?.toUpperCase() === RequestEnum.GET) {
			if (!isString(params)) {
				// 给 get 请求加上时间戳参数，避免从缓存中拿数据。
				config.params = Object.assign(params || {}, joinTimestamp(joinTime, false));
			} else {
				// 兼容restful风格
				config.url = config.url + params + `${joinTimestamp(joinTime, true)}`;
				config.params = undefined;
			}
		} else {
			if (!isString(params)) {
				formatDate && formatRequestDate(params);
				if (Reflect.has(config, "data") && config.data && Object.keys(config.data).length > 0) {
					config.data = data;
					config.params = params;
				} else {
					config.data = params;
					config.params = undefined;
				}
				if (joinParamsToUrl) {
					config.url = setObjToUrlParams(config.url as string, Object.assign({}, config.params, config.data));
				}
			} else {
				// 兼容restful风格
				config.url = config.url + params;
				config.params = undefined;
			}
		}
		return config;
	},

	/**
	 * @description: 请求拦截器处理
	 */
	requestInterceptors: (config, options) => {
		// 请求之前处理config
		// const userStore = useUser();
		// const token = userStore.getToken;
		const token = storage.getCookie(import.meta.env.VITE_GLOB_TOKEN_KEY) || "";
		// const { token } = useToken();
		if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
			// jwt token
			(config as Recordable).headers.Authorization = options.authenticationScheme
				? `${options.authenticationScheme} ${token}`
				: token;
		}
		return config;
	},

	/**
	 * @description: 响应错误处理
	 */
	responseInterceptorsCatch: (error: any) => {
		const { response, code, message } = error || {};
		// TODO 此处要根据后端接口返回格式修改
		const msg: string = response && response.data && response.data.message ? response.data.message : "";
		const err: string = error.toString();
		try {
			if (code === "ECONNABORTED" && message.indexOf("timeout") !== -1) {
				notification.error({ message: "接口请求错误", description: "接口请求超时，请刷新页面重试!" });
				return;
			}
			if (err && err.includes("Network Error")) {
				notification.error({ message: "网络异常", description: "请检查您的网络连接是否正常!" });
				return Promise.reject(error);
			}
		} catch (error) {
			throw new Error(error as any);
		}
		// 请求是否被取消
		const isCancel = axios.isCancel(error);
		if (!isCancel) {
			checkStatus(error.response && error.response.status, msg);
		} else {
			console.warn(error, "请求被取消！");
		}
		return Promise.reject(response?.data);
	}
};

function createAxios(opt?: Partial<CreateAxiosOptions>) {
	return new VAxios(
		deepMerge(
			{
				timeout: 10 * 1000,
				authenticationScheme: import.meta.env.VITE_GLOB_TOKEN_HEADER || " ",
				// 接口前缀
				prefixUrl: urlPrefix,
				headers: { "Content-Type": ContentTypeEnum.JSON, Clientid: clientId },
				// 数据处理方式
				transform,
				// 配置项，下面的选项都可以在独立的接口请求中覆盖
				requestOptions: {
					// 默认将prefix 添加到url
					joinPrefix: true,
					// 是否返回原生响应头 比如：需要获取响应头时使用该属性
					isReturnNativeResponse: false,
					// 需要对返回数据进行处理
					isTransformResponse: false,
					// post请求的时候添加参数到url
					joinParamsToUrl: false,
					// 格式化提交参数时间
					formatDate: true,
					// 消息提示类型
					errorMessageMode: "none",
					// 接口地址
					// apiUrl: "http://127.0.0.1:8080",
					// 接口拼接地址
					urlPrefix: urlPrefix,
					//  是否加入时间戳
					joinTime: true,
					// 忽略重复请求
					ignoreCancelToken: true,
					// 是否携带token
					withToken: true
				},
				withCredentials: false
			},
			opt || {}
		)
	);
}
const global = {
	TokenInvalidFlag: 0
} as any;
const handleSwitch = (data: Result<any>) => {
	let errorMsg = data.msg;
	const code = data.code || 200;

	switch (code) {
		// 请求失败
		case ResultEnum.ERROR:
			message.error(errorMsg);
			break;
		//没有权限
		case ResultEnum.NOT_PRMISSION:
			message.error(errorMsg);
			break;
		// 登录超时
		case ResultEnum.TIMEOUT:
			// 到登录页
			errorMsg = "登录超时，请重新登录!";
			Modal.warning({
				title: "提示",
				content: errorMsg,
				okText: "重新登录",
				onOk: () => {
					window.location.href = PageEnum.LOGIN_PATH;
				}
			});
			break;
		case ResultEnum.NOT_AUTH:
			if (global.TokenInvalidFlag == 0) {
				//删除用户信息
				localStorage.clear();
				// token无效标记置1
				global.TokenInvalidFlag = 1;
				axiosCanceler.removeAllPending();
				Modal.warning({
					title: "登录过期提示",
					content: errorMsg,
					okText: "重新登录",
					onOk: () => {
						const pre = window.location.origin;
						window.location.href = `${pre}${PageEnum.LOGIN_PATH}?redirectUrl=${encodeURIComponent(window.location.href)}`;
					}
				});
			}
			break;
	}
};

export const http = createAxios();

// 项目，多个不同 api 地址，直接在这里导出多个
// src/api ts 里面接口，就可以单独使用这个请求，
// import { httpTwo } from '@/utils/http/axios'
// export const httpTwo = createAxios({
//   requestOptions: {
//     apiUrl: 'http://localhost:9001',
//     urlPrefix: 'api',
//   },
// });
